/*
 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup OH_NativeXComponent Native XComponent
 * @{
 *
 * @brief Describes the surface and touch event held by the ArkUI XComponent, which can be used for the EGL/OpenGL ES and media data input and displayed on the ArkUI XComponent.
 *
 * @since 8
 * @version 1.0
 */

/**
 * @file native_interface_xcomponent.h
 *
 * @brief Declares the APIs used to access the native XComponent.
 *
 * @since 8
 * @version 1.0
 */

#ifndef _NATIVE_INTERFACE_XCOMPONENT_H_
#define _NATIVE_INTERFACE_XCOMPONENT_H_

#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Enumerates the API access states.
 *
 * @since 8
 * @version 1.0
 */
enum {
    /** Success result. */
    OH_NATIVEXCOMPONENT_RESULT_SUCCESS = 0,
    /** Failure. */
    OH_NATIVEXCOMPONENT_RESULT_FAILED = -1,
    /** Invalid parameter. */
    OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER = -2,
};

/**
 * @brief Enumerates the touch event types.
 * @since 8
 */
typedef enum {
    /** The touch event is triggered when a finger is pressed. */
    OH_NATIVEXCOMPONENT_DOWN = 0,
    /** The touch event is triggered when a finger is lifted. */
    OH_NATIVEXCOMPONENT_UP,
    /** The touch event is triggered when a finger is pressed and moves on the screen. */
    OH_NATIVEXCOMPONENT_MOVE,
    /** The event is triggered when a touch event is canceled. */
    OH_NATIVEXCOMPONENT_CANCEL,
    /** Invalid touch type. */
    OH_NATIVEXCOMPONENT_UNKNOWN,
} OH_NativeXComponent_TouchEventType;

/**
 * @brief Enumerates the contact point tool types.
 *
 * @since 9
 * @version 1.0
 */
typedef enum {
    /** Unknown tool type. */
    OH_NATIVEXCOMPONENT_TOOL_TYPE_UNKNOWN = 0,
    /** Finger. */
    OH_NATIVEXCOMPONENT_TOOL_TYPE_FINGER,
    /** Stylus. */
    OH_NATIVEXCOMPONENT_TOOL_TYPE_PEN,
    /** Eraser. */
    OH_NATIVEXCOMPONENT_TOOL_TYPE_RUBBER,
    /** Brush. */
    OH_NATIVEXCOMPONENT_TOOL_TYPE_BRUSH,
    /**Pencil. */
    OH_NATIVEXCOMPONENT_TOOL_TYPE_PENCIL,
    /** Air brush. */
    OH_NATIVEXCOMPONENT_TOOL_TYPE_AIRBRUSH,
    /** Mouse. */
    OH_NATIVEXCOMPONENT_TOOL_TYPE_MOUSE,
    /** Lens. */
    OH_NATIVEXCOMPONENT_TOOL_TYPE_LENS,
} OH_NativeXComponent_TouchPointToolType;

/**
 * @brief Enumerates the source types of the touch event.
 *
 * @since 9
 * @version 1.0
 */
typedef enum {
    /** Unknown source type. */
    OH_NATIVEXCOMPONENT_SOURCE_TYPE_UNKNOWN = 0,
    /** Source that generates a mouse multi-touch event. */
    OH_NATIVEXCOMPONENT_SOURCE_TYPE_MOUSE,
    /** Source that generates a touchscreen multi-touch event. */
    OH_NATIVEXCOMPONENT_SOURCE_TYPE_TOUCHSCREEN,
    /** Source that generates a touchpad multi-touch event. */
    OH_NATIVEXCOMPONENT_SOURCE_TYPE_TOUCHPAD,
    /** Source that generates a joystick multi-touch event. */
    OH_NATIVEXCOMPONENT_SOURCE_TYPE_JOYSTICK,
} OH_NativeXComponent_EventSourceType;

/**
 * @brief Enumerates the mouse event actions.
 *
 * @since 9
 * @version 1.0
 */
typedef enum {
    /** Invalid mouse event. */
    OH_NATIVEXCOMPONENT_MOUSE_NONE = 0,
    /** The mouse event is triggered when a mouse button is pressed. */
    OH_NATIVEXCOMPONENT_MOUSE_PRESS,
    /** The mouse event is triggered when a mouse button is released. */
    OH_NATIVEXCOMPONENT_MOUSE_RELEASE,
    /** The mouse event is triggered when the mouse moves on the screen. */
    OH_NATIVEXCOMPONENT_MOUSE_MOVE,
} OH_NativeXComponent_MouseEventAction;

/**
 * @brief Enumerates the mouse event buttons.
 *
 * @since 9
 * @version 1.0
 */
typedef enum {
    /** The mouse event is triggered when no mouse button is pressed. */
    OH_NATIVEXCOMPONENT_NONE_BUTTON = 0,
    /** The mouse event is triggered when the left mouse button is pressed. */
    OH_NATIVEXCOMPONENT_LEFT_BUTTON = 0x01,
    /** The mouse event is triggered when the right mouse button is pressed. */
    OH_NATIVEXCOMPONENT_RIGHT_BUTTON = 0x02,
    /** The mouse event is triggered when the middle mouse button is pressed. */
    OH_NATIVEXCOMPONENT_MIDDLE_BUTTON = 0x04,
    /** The mouse event is triggered when the back button on the left of the mouse is pressed. */
    OH_NATIVEXCOMPONENT_BACK_BUTTON = 0x08,
    /** The mouse event is triggered when the forward button on the left of the mouse is pressed. */
    OH_NATIVEXCOMPONENT_FORWARD_BUTTON = 0x10,
} OH_NativeXComponent_MouseEventButton;

#define OH_NATIVE_XCOMPONENT_OBJ ("__NATIVE_XCOMPONENT_OBJ__")
const uint32_t OH_XCOMPONENT_ID_LEN_MAX = 128;
const uint32_t OH_MAX_TOUCH_POINTS_NUMBER = 10;

typedef struct {
    /** Unique identifier of the finger. */
    int32_t id = 0;
    /** X coordinate of the touch point relative to the upper left corner of the application window where the XComponent is located. */
    float screenX = 0.0;
    /** Y coordinate of the touch point relative to the upper left corner of the application window where the XComponent is located. */
    float screenY = 0.0;
    /** X coordinate of the touch point relative to the left edge of the XComponent. */
    float x = 0.0;
    /** Y coordinate of the touch point relative to the upper edge of the XComponent. */
    float y = 0.0;
    /** Touch type of the touch event. */
    OH_NativeXComponent_TouchEventType type = OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UNKNOWN;
    /** Contact area between the finger pad and the screen. */
    double size = 0.0;
    /** Pressure of the current touch event. */
    float force = 0.0;
    /** Timestamp of the current touch event. */
    long long timeStamp = 0;
    /** Whether the current point is pressed. */
    bool isPressed = false;
} OH_NativeXComponent_TouchPoint;

/**
 * @brief Describes the touch event.
 *
 * @since 8
 * @version 1.0
 */
typedef struct {
    /** Unique identifier of the finger. */
    int32_t id = 0;
    /** X coordinate of the touch point relative to the left edge of the screen. */
    float screenX = 0.0;
    /** Y coordinate of the touch point relative to the upper edge of the screen. */
    float screenY = 0.0;
    /** X coordinate of the touch point relative to the left edge of the XComponent. */
    float x = 0.0;
    /** Y coordinate of the touch point relative to the upper edge of the XComponent. */
    float y = 0.0;
    /** Touch type of the touch event. */
    OH_NativeXComponent_TouchEventType type = OH_NativeXComponent_TouchEventType::OH_NATIVEXCOMPONENT_UNKNOWN;
    /** Contact area between the finger pad and the screen. */
    double size = 0.0;
    /** Pressure of the current touch event. */
    float force = 0.0;
    /** ID of the device where the current touch event is triggered. */
    int64_t deviceId = 0;
    /** Timestamp of the current touch event. */
    long long timeStamp = 0;
    /** Array of the current touch points. */
    OH_NativeXComponent_TouchPoint touchPoints[OH_MAX_TOUCH_POINTS_NUMBER];
    /** Number of current touch points. */
    uint32_t numPoints = 0;
} OH_NativeXComponent_TouchEvent;

/**
 * @brief Describes the mouse event.
 *
 * @since 9
 * @version 1.0
 */
typedef struct {
    /** X coordinate of the clicked point relative to the upper left corner of the component. */
    float x;
    /** Y coordinate of the clicked point relative to the upper left corner of the component. */
    float y;
    /** X coordinate of the clicked point relative to the upper left corner of the screen. */
    float screenX;
    /** Y coordinate of the clicked point relative to the upper left corner of the screen. */
    float screenY;
    /** Timestamp of the current mouse event. */
    int64_t timestamp;
    /** Current mouse event action. */
    OH_NativeXComponent_MouseEventAction action;
    /** Mouse event button */
    OH_NativeXComponent_MouseEventButton button;
} OH_NativeXComponent_MouseEvent;

/**
 * @brief Provides an encapsulated OH_NativeXComponent instance.
 *
 * @since 8
 * @version 1.0
 */
typedef struct OH_NativeXComponent OH_NativeXComponent;

/**
 * @brief Registers a callback for the surface lifecycle and touch event.
 *
 * @since 8
 * @version 1.0
 */
typedef struct OH_NativeXComponent_Callback {
    /** Invoked when a surface is created. */
    void (*OnSurfaceCreated)(OH_NativeXComponent* component, void* window);
    /** Invoked when the surface changes. */
    void (*OnSurfaceChanged)(OH_NativeXComponent* component, void* window);
    /** Invoked when the surface is destroyed. */
    void (*OnSurfaceDestroyed)(OH_NativeXComponent* component, void* window);
    /** Invoked when a touch event is triggered. */
    void (*DispatchTouchEvent)(OH_NativeXComponent* component, void* window);
} OH_NativeXComponent_Callback;

/**
 * @brief Registers a callback for the mouse event.
 *
 * @since 9
 * @version 1.0
 */
typedef struct OH_NativeXComponent_MouseEvent_Callback {
    /** Invoked when a mouse event is triggered. */
    void (*DispatchMouseEvent)(OH_NativeXComponent* component, void* window);
    /** Invoked when a hover event is triggered. */
    void (*DispatchHoverEvent)(OH_NativeXComponent* component, bool isHover);
} OH_NativeXComponent_MouseEvent_Callback;

/**
 * @brief Obtains the ID of the ArkUI XComponent.
 *
 * @param component Indicates the pointer to an <b>OH_NativeXComponent</b> instance.
 * @param id Indicates the pointer to the character buffer used to hold the ID of the OH_NativeXComponent instance.
 *        Note that the null terminator is attached to the character buffer, so the size of the character buffer should be at least one unit greater than the length of the real ID.
 *        The recommended size of the character buffer is [OH_XCOMPONENT_ID_LEN_MAX + 1].
 * @param size Indicates the pointer to the length of the ID.
 * @return Returns the status code of the operation.
 * @since 8
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetXComponentId(OH_NativeXComponent* component, char* id, uint64_t* size);

/**
 * @brief Obtains the size of the surface held by the ArkUI XComponent.
 *
 * @param component Indicates the pointer to an <b>OH_NativeXComponent</b> instance.
 * @param window Indicates the pointer to a <b>NativeWindow</b> handle.
 * @param width Indicates the pointer to the width of the current surface.
 * @param height Indicates the pointer to the height of the current surface.
 * @return Returns the status code of the operation.
 * @since 8
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetXComponentSize(
    OH_NativeXComponent* component, const void* window, uint64_t* width, uint64_t* height);

/**
 * @brief Obtains the offset of the ArkUI XComponent relative to the upper left vertex of the screen.
 *
 * @param component Indicates the pointer to an <b>OH_NativeXComponent</b> instance.
 * @param window Indicates the pointer to a <b>NativeWindow</b> handle.
 * @param x Indicates the pointer to the x coordinate of the current surface.
 * @param y Indicates the pointer to the y coordinate of the current surface.
 * @return Returns the status code of the operation.
 * @since 8
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetXComponentOffset(
    OH_NativeXComponent* component, const void* window, double* x, double* y);

/**
 * @brief Obtains the touch event scheduled by the ArkUI XComponent.
 *
 * @param component Indicates the pointer to an <b>OH_NativeXComponent</b> instance.
 * @param window Indicates the pointer to a <b>NativeWindow</b> handle.
 * @param touchEvent Indicates the pointer to the current touch event.
 * @return Returns the status code of the operation.
 * @since 8
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetTouchEvent(
    OH_NativeXComponent* component, const void* window, OH_NativeXComponent_TouchEvent* touchEvent);

/**
 * @brief Obtains the ArkUI XComponent touch point tool type.
 * @param component Indicates the pointer to an <b>OH_NativeXComponent</b> instance.
 * @param pointIndex Indicates the index of the pointer to a touch point.
 * @param toolType Indicates the pointer to the tool type.
 * @return Returns the status code of the operation.
 * @since 9
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetTouchPointToolType(OH_NativeXComponent* component, uint32_t pointIndex,
    OH_NativeXComponent_TouchPointToolType* toolType);

/**
 * @brief Obtains the angle between the tilt of the ArkUI XComponent touch point and the x-axis.
 *
 * @param component Indicates the pointer to an <b>OH_NativeXComponent</b> instance.
 * @param pointIndex Indicates the index of the pointer to a touch point.
 * @param tiltX Indicates the pointer to the tilt along the x-axis.
 * @return Returns the status code of the operation.
 * @since 9
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetTouchPointTiltX(OH_NativeXComponent* component, uint32_t pointIndex, float* tiltX);

/**
 * @brief Obtains the angle between the tilt of the ArkUI XComponent touch point and the y-axis.
 *
 * @param component Indicates the pointer to an <b>OH_NativeXComponent</b> instance.
 * @param pointIndex Indicates the index of the pointer to a touch point.
 * @param tiltY Indicates the pointer to the tilt along the y-axis.
 * @return Returns the status code of the operation.
 * @since 9
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetTouchPointTiltY(OH_NativeXComponent* component, uint32_t pointIndex, float* tiltY);

/**
 * @brief Obtains the mouse event scheduled by ArkUI XComponent.
 *
 * @param component Indicates the pointer to an <b>OH_NativeXComponent</b> instance.
 * @param window Indicates the pointer to a <b>NativeWindow</b> handle.
 * @param mouseEvent Indicates the pointer to the current mouse event.
 * @return Returns the status code of the operation.
 * @since 9
 * @version 1.0
 */
int32_t OH_NativeXComponent_GetMouseEvent(
    OH_NativeXComponent* component, const void* window, OH_NativeXComponent_MouseEvent* mouseEvent);

/**
 * @brief Registers a callback for this <b>OH_NativeXComponent</b> instance.
 *
 * @param component Indicates the pointer to an <b>OH_NativeXComponent</b> instance.
 * @param callback Indicates the pointer to the surface lifecycle and touch event callback.
 * @return Returns the status code of the operation.
 * @since 8
 * @version 1.0
 */
int32_t OH_NativeXComponent_RegisterCallback(OH_NativeXComponent* component, OH_NativeXComponent_Callback* callback);

/**
 * @brief Registers a mouse event callback for this <b>OH_NativeXComponent</b> instance.
 *
 * @param component Indicates the pointer to an <b>OH_NativeXComponent</b> instance.
 * @param callback Indicates the pointer to the mouse event callback.
 * @return Returns the status code of the operation.
 * @since 9
 * @version 1.0
 */
int32_t OH_NativeXComponent_RegisterMouseEventCallback(
    OH_NativeXComponent* component, OH_NativeXComponent_MouseEvent_Callback* callback);
#ifdef __cplusplus
};
#endif
#endif // _NATIVE_INTERFACE_XCOMPONENT_H_
